3 dimensional matching / 3х-мерное сочетание
Постановка задачи
«3DM», «3-мерное сопоставление» представляет собой обобщение «задачи о максимальном паросочетании» на 3х-дольные гиперграфы, которые состоят из гиперребер, каждое из которых содержит 3 вершины (вместо ребер, содержащих 2 вершины в случае обычного графа).
Задача состоит в поиске наибольшего трехмерного сопоставления в заданном гиперграфе. 3DM — одна из первых задач, которые оказались NP-сложными.
Реализация в Pyomo
| | видео |
Сведение из википедии с вариациями
Множество
Заводим для каждого упоминания литерала два узла, — сам литерал с номером, какой он по счету (неважно, в каких скобках он был), и его двойник-отрицание.
Основная логика — какая нода войдет в максимальное сочетание в тройкахе с переменными y-z типа «C» — это и определит присваивание для SAT (так то в максимальное паросочетание войдут все)
войдет , т.е. 4-е упоминание — значит,
войдет , т.е. отрицательный литерал для 2-го упоминания — значит,
Отдельно конечно надо обеспечить, что если вошел , то должны войти в сочетание и остальные упоминания , … и не должный войти их отрицательные двойники.
Множество ,
Разные вспомогательные переменные, их смысл будет ниже.
Гаджет «Роза» для каждой скобки
Соединяем ноды (литерал этой скобки с номером, какой он по порядку)
«Сборка мусора»
Но надо бы покрыть и остальные узлы!
Гаджет «Колесо» — сведение переменных
Да, такое вот, «Колесо»
||||
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/var/data/cocalc/1d588dae-0d14-422a-88b4-c470ec2c8303/hard-problems-formulations/maximum-3-dimensional-matching.ipynb Cell 40 line 1
----> <a href='vscode-notebook-cell://xn--17-6kce2c.xn--80apqgfe.xn--p1ai/var/data/cocalc/1d588dae-0d14-422a-88b4-c470ec2c8303/hard-problems-formulations/maximum-3-dimensional-matching.ipynb#X54sdnNjb2RlLXJlbW90ZQ%3D%3D?line=0'>1</a> m_ = variable23dm(cnf, 2)
<a href='vscode-notebook-cell://xn--17-6kce2c.xn--80apqgfe.xn--p1ai/var/data/cocalc/1d588dae-0d14-422a-88b4-c470ec2c8303/hard-problems-formulations/maximum-3-dimensional-matching.ipynb#X54sdnNjb2RlLXJlbW90ZQ%3D%3D?line=1'>2</a> SVG(psc.matchings2svg(m_))
/var/data/cocalc/1d588dae-0d14-422a-88b4-c470ec2c8303/hard-problems-formulations/maximum-3-dimensional-matching.ipynb Cell 40 line 1
<a href='vscode-notebook-cell://xn--17-6kce2c.xn--80apqgfe.xn--p1ai/var/data/cocalc/1d588dae-0d14-422a-88b4-c470ec2c8303/hard-problems-formulations/maximum-3-dimensional-matching.ipynb#X54sdnNjb2RlLXJlbW90ZQ%3D%3D?line=15'>16</a> vn = abs(lit)
<a href='vscode-notebook-cell://xn--17-6kce2c.xn--80apqgfe.xn--p1ai/var/data/cocalc/1d588dae-0d14-422a-88b4-c470ec2c8303/hard-problems-formulations/maximum-3-dimensional-matching.ipynb#X54sdnNjb2RlLXJlbW90ZQ%3D%3D?line=16'>17</a> k += 1
---> <a href='vscode-notebook-cell://xn--17-6kce2c.xn--80apqgfe.xn--p1ai/var/data/cocalc/1d588dae-0d14-422a-88b4-c470ec2c8303/hard-problems-formulations/maximum-3-dimensional-matching.ipynb#X54sdnNjb2RlLXJlbW90ZQ%3D%3D?line=17'>18</a> bp = lit2vertix(cnf, vn, k)
<a href='vscode-notebook-cell://xn--17-6kce2c.xn--80apqgfe.xn--p1ai/var/data/cocalc/1d588dae-0d14-422a-88b4-c470ec2c8303/hard-problems-formulations/maximum-3-dimensional-matching.ipynb#X54sdnNjb2RlLXJlbW90ZQ%3D%3D?line=18'>19</a> bn = lit2vertix(cnf, -vn, k)
<a href='vscode-notebook-cell://xn--17-6kce2c.xn--80apqgfe.xn--p1ai/var/data/cocalc/1d588dae-0d14-422a-88b4-c470ec2c8303/hard-problems-formulations/maximum-3-dimensional-matching.ipynb#X54sdnNjb2RlLXJlbW90ZQ%3D%3D?line=19'>20</a> match.append([bp, f'y_{{{vn}}}^{{{k}}}', f'z_{{{vn}}}^{{{k}}}'])
NameError: name 'lit2vertix' is not defined
Получится взять либо все «положительные b» либо все отрицательные «b», причем «наоборот» по смыслу.